#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/syscall.h>
#ifdef __ANDROID__
#include <android/log.h>
#endif
#include "CIpodLog.h"

#define NONE                "\033[m"
#define DARY_GRAY           "\033[1;30m"
#define RED                 "\033[0;32;31m"
#define LIGHT_RED           "\033[1;31m"
#define GREEN               "\033[0;32;32m"
#define LIGHT_GREEN         "\033[1;32m"
#define BROWN               "\033[0;33m"
#define YELLOW              "\033[1;33m"
#define BLUE                "\033[0;32;34m"
#define LIGHT_BLUE          "\033[1;34m"
#define PURPLE              "\033[0;35m"
#define LIGHT_PURPLE        "\033[1;35m"
#define CYAN                "\033[0;36m"
#define LIGHT_CYAN          "\033[1;36m"
#define LIGHT_GRAY          "\033[0;37m"
#define WHITE               "\033[1;37m"

#define IPOD_LOG_ERROR      0
#define IPOD_LOG_WARN       1
#define IPOD_LOG_INFO       2
#define IPOD_LOG_DEBUG      3

#define LOG_TAG             "IAP2"
#define TIME_BUF_SIZE       128
int CIpodLog::s_LogLevel    = IPOD_LOG_DEBUG;

void CIpodLog::init() {
    char *logLevel = getenv("IPOD_LOG_LEVEL");
    if (logLevel != NULL) {
        s_LogLevel = atoi(logLevel);
    }
}

void CIpodLog::e(const char *format, ...) {
    if (s_LogLevel >= IPOD_LOG_ERROR) {
        va_list vas;
        va_start(vas, format);
#ifdef __ANDROID__
        __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, vas);
#else
        char buf[TIME_BUF_SIZE];
        getSystemTime(buf);
        fprintf( stderr, RED"%s[%u,ERROR] ", buf, syscall( SYS_gettid ) );
        vfprintf( stderr, format, vas );
        fprintf( stderr, NONE );
#endif
        va_end(vas);
    }
}

void CIpodLog::w(const char *format, ...) {
    if (s_LogLevel >= IPOD_LOG_WARN) {
        va_list vas;
        va_start(vas, format);
#ifdef __ANDROID__
        __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, vas);
#else
        char buf[TIME_BUF_SIZE];
        getSystemTime(buf);
        fprintf(stderr, YELLOW"%s[%u,WARN] ", buf, syscall( SYS_gettid ) );
        vfprintf(stderr, format, vas);
        fprintf( stderr, NONE );
#endif
        va_end(vas);
    }
}

void CIpodLog::i(const char *format, ...) {
    if (s_LogLevel >= IPOD_LOG_INFO) {
        va_list vas;
        va_start(vas, format);
#ifdef __ANDROID__
        __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, vas);
#else
        char buf[TIME_BUF_SIZE];
        getSystemTime(buf);
        fprintf(stderr, BLUE"%s[%u,INFO] ", buf, syscall( SYS_gettid ) );
        vfprintf(stderr, format, vas);
        fprintf( stderr, NONE );
#endif
        va_end(vas);
    }
}

void CIpodLog::d(const char *format, ...) {
    if (s_LogLevel >= IPOD_LOG_DEBUG) {
        va_list vas;
        va_start(vas, format);
#ifdef __ANDROID__
        __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, vas);
#else
        char buf[TIME_BUF_SIZE];
        getSystemTime(buf);
        fprintf(stderr, LIGHT_GRAY"%s[%u,INFO] ", buf, syscall( SYS_gettid ) );
        vfprintf(stderr, format, vas);
        fprintf( stderr, NONE );
#endif
        va_end(vas);
    }
}

void CIpodLog::getSystemTime(char *buf)
{
    if( !buf )	return;

    struct timeval		now;
    time_t			nowTT;
    struct tm *			nowTM;
    char			dateTimeStr[ 24 ];
    char			amPMStr[ 8 ];

    gettimeofday( &now, NULL );
    nowTT = now.tv_sec;
    nowTM = localtime( &nowTT );
    strftime( dateTimeStr, sizeof( dateTimeStr ), "%Y-%m-%d %I:%M:%S", nowTM );
    strftime( amPMStr, sizeof( amPMStr ), "%p", nowTM );

    sprintf( buf, "%s.%06u %s ", dateTimeStr, now.tv_usec, amPMStr );
}
